using System;
using System.Drawing;

namespace Wilco.SyntaxHighlighting
{
	/// <summary>
	/// Represents a COBOL syntax highlighter.
	/// </summary>
	public class CobolHighlighter : HighlighterBase
	{
		/// <summary>
		/// Initializes a new instance of a <see cref="Wilco.SyntaxHighlighting.CobolHighlighter"/> class.
		/// </summary>
		public CobolHighlighter() : this(null)
		{
			//
		}

		/// <summary>
		/// Initializes a new instance of a <see cref="Wilco.SyntaxHighlighting.CobolHighlighter"/> class.
		/// </summary>
		/// <param name="parser">The parser which will be used to parse the source code.</param>
		public CobolHighlighter(IParser parser) : base(parser)
		{
			this.Name = "COBOL";
			this.FullName = "COBOL";
			this.TagValues.AddRange(new String[] { "cob" });
			this.FileExtensions.Add("cob");
		}

        /// <summary>
        /// Creates a new instance (clone) of this highlighter.
        /// </summary>
        /// <returns></returns>
        public override HighlighterBase Create()
        {
            return new CobolHighlighter(this.Parser);
        }

		/// <summary>
		/// Builds a word scanner.
		/// </summary>
		/// <returns>A <see cref="Wilco.SyntaxHighlighting.WordScanner"/> object.</returns>
		protected override IScanner BuildWordScanner()
		{
			WordScanner scanner = new WordScanner(this.Tokenizer, this.ScannerResult);
			scanner.WordNodes = new WordNode[1];
			scanner.WordNodes[0] = new WordNode();
			scanner.WordNodes[0].ForeColor = Color.Blue;
			scanner.WordNodes[0].Entities.AddRange(this.GetKeywords());
			return scanner;
		}

		/// <summary>
		/// Gets an array of registered keywords.
		/// </summary>
		/// <returns>An array of keywords.</returns>
		private string[] GetKeywords()
		{
			string[] keywordList = new string[]
			{
				"ACCEPT",
				"ACCESS",
				"ACTUAL",
				"ADD",
				"ADDRESS",
				"ADVANCING",
				"AFTER",
				"ALL",
				"ALPHABET",
				"ALPHABETIC",
				"ALPHABETIC-LOWER",
				"ALPHABETIC-UPPER",
				"ALPHANUMERIC",
				"ALPHANUMERIC-EDITED",
				"ALS",
				"ALTER",
				"ALTERNATE",
				"AND",
				"ANY",
				"APPLY",
				"ARE",
				"AREA",
				"AREAS",
				"ARITHMETIC",
				"AS",
				"ASCENDING",
				"ASSIGN",
				"AT",
				"AUTHOR",
				"AUTO",
				"AUTOMATIC",
				"B-AND",
				"B-EXOR",
				"B-LESS",
				"B-NOT",
				"B-OR",
				"BASED",
				"BACKGROUND-COLOR",
				"BASED-STORAGE",
				"BEFORE",
				"BEGINNING",
				"BELL",
				"BINARY",
				"BIT",
				"BITS",
				"BLANK",
				"BLINK",
				"BLOCK",
				"BOOLEAN",
				"BOTTOM",
				"BY",
				"CALL",
				"CANCEL",
				"CBL",
				"CD",
				"CF",
				"CH",
				"CHANGED",
				"CHARACTER",
				"CHARACTERS",
				"CLASS",
				"CLASS-ID",
				"CLOCK-UNITS",
				"CLOSE",
				"COBOL",
				"CODE",
				"CODE-SET",
				"COLLATING",
				"COLUMN",
				"COMMA",
				"COMMAND",
				"COMMIT",
				"COMMON",
				"COMMUNICATION",
				"COM-REG",
				"COMP",
				"COMP-1",
				"COMP-2",
				"COMP-3",
				"COMP-4",
				"COMP-5",
				"COMP-n",
				"COMPLEX",
				"COMPUTATIONAL",
				"COMPUTATIONAL-1",
				"COMPUTATIONAL-2",
				"COMPUTATIONAL-3",
				"COMPUTATIONAL-4",
				"COMPUTATIONAL-5",
				"COMPUTATIONAL-n",
				"COMPUTE",
				"CONFIGURATION",
				"CONNECT",
				"CONSTANT",
				"CONTAINED",
				"CONTAINS",
				"CONTENT",
				"CONTINUE",
				"CONTROL",
				"CONTROL-CHARACTER",
				"CONTROLS",
				"CONVERTING",
				"COPY",
				"CORE-INDEX",
				"CORR",
				"CORRESPONDING",
				"COUNT",
				"CRP",
				"CRT",
				"CRT-UNDER",
				"CURRENCY",
				"CURRENT",
				"CURSOR",
				"DATA",
				"DATE",
				"DATE-COMPILED",
				"DATE-WRITTEN",
				"DAY",
				"DAY-OF-WEEK",
				"DB",
				"DB-ACCESS-CONTROL-KEY",
				"DB-DATA-NAME",
				"DB-EXCEPTION",
				"DB-RECORD-NAME",
				"DB-SET-NAME",
				"DB-STATUS",
				"DE",
				"DEAD-LOCK",
				"DEBUG-CONTENTS",
				"DEBUG-ITEM",
				"DEBUG-LINE",
				"DEBUG-NAME",
				"DEBUG-SUB-1",
				"DEBUG-SUB-2",
				"DEBUG-SUB-3",
				"DEBUGGING",
				"DECIMAL-POINT",
				"DECLARATIVES",
				"DEFAULT",
				"DELETE",
				"DELIMITED",
				"DELIMITER",
				"DEPENDING",
				"DESCENDING",
				"DESTINATION",
				"DESTINATION-1",
				"DESTINATION-2",
				"DESTINATION-3",
				"DETAIL",
				"DEVICE",
				"DIRECT",
				"DISABLE",
				"DISCONNECT",
				"DISJOINING",
				"DISPLAY",
				"DISPLAY-1",
				"DISPLAY-EXIT",
				"DISPLAY-n",
				"DIVIDE",
				"DIVISION",
				"DOWN",
				"DUPLICATE",
				"DUPLICATES",
				"DYNAMIC",
				"EDIT-COLOR",
				"EDIT-CURSOR",
				"EDIT-MODE",
				"EDIT-OPTION",
				"EDIT-STATUS",
				"EGCS",
				"EGI",
				"EJECT",
				"ELSE",
				"EMI",
				"EMPTY",
				"ENABLE",
				"END",
				"END-ACCEPT",
				"END-ADD",
				"END-CALL",
				"END-COMPUTE",
				"END-DELETE",
				"END-DISABLE",
				"END-DISPLAY",
				"END-DIVIDE",
				"END-ENABLE",
				"END-EVALUATE",
				"END-EXEC",
				"END-IF",
				"END-INVOKE",
				"END-MULTIPLY",
				"END-OF-PAGE",
				"END-PERFORM",
				"END-READ",
				"END-RECEIVE",
				"END-RETURN",
				"END-REWRITE",
				"END-SEARCH",
				"END-SEND",
				"END-START",
				"END-STRING",
				"END-SUBTRACT",
				"END-TRANSCEIVE",
				"END-UNSTRING",
				"END-WRITE",
				"ENDCOBOL",
				"ENDING",
				"ENTER",
				"ENTRY",
				"ENVIRONMENT",
				"EOL",
				"EOP",
				"EOS",
				"EQUAL",
				"EQUALS",
				"ERASE",
				"ERROR",
				"ESI",
				"EVALUATE",
				"EVERY",
				"EXACT",
				"EXAMINE",
				"EXCEEDS",
				"EXCEPTION",
				"EXCEPTION-OBJECT",
				"EXCLUSIVE",
				"EXEC",
				"EXIT",
				"EXOR",
				"EXTEND",
				"EXTERNAL",
				"FACTORY",
				"FALSE",
				"FD",
				"FETCH",
				"FILE",
				"FILE-CONTROL",
				"FILE-LIMIT",
				"FILE-LIMITS",
				"FILES",
				"FILLER",
				"FINAL",
				"FIND",
				"FINISH",
				"FIRST",
				"FLADD",
				"FOOTING",
				"FOR",
				"FOREGROUND-COLOR",
				"FORM",
				"FORMAT",
				"FORMATTED",
				"FREE",
				"FROM",
				"FULL",
				"FUNCTION",
				"GENERATE",
				"GET",
				"GIVING",
				"GLOBAL",
				"G",
				"GOBACK",
				"GREATER",
				"GRID",
				"GROUP",
				"HEADING",
				"HIGHLIGHT",
				"HIGH-VALUE",
				"HIGH-VALUES",
				"I-",
				"I-O-CONTROL",
				"ID",
				"IDENTIFICATION",
				"IF",
				"IN",
				"INCLUDE",
				"INDEX",
				"INDEX-n",
				"INDEXED",
				"INDICATE",
				"INHERITS",
				"INITIAL",
				"INITIALIZE",
				"INITIATE",
				"INPUT",
				"INPUT-OUTPUT",
				"INSPECT",
				"INSTALLATION",
				"INT",
				"INVALID",
				"INVARIANT",
				"INVOKE",
				"IS",
				"JAPANESE",
				"JOB",
				"JOINING",
				"JUST",
				"JUSTIFIED",
				"KANJI",
				"KEEP",
				"KEY",
				"LABEL",
				"LAST",
				"LD",
				"LEADING",
				"LEFT",
				"LEFTLINE",
				"LEFT-JUSTIFY",
				"LENGTH",
				"LESS",
				"LIMIT",
				"LIMITED",
				"LIMITS",
				"LINAGE",
				"LINAGE-COUNTER",
				"LINE",
				"LINE-COUNTER",
				"LINES",
				"LINKAGE",
				"LOCALLY",
				"LOCK",
				"LOW-VALUE",
				"LOW-VALUES",
				"LOWLIGHT",
				"MANUAL",
				"MEMBER",
				"MEMORY",
				"MERGE",
				"MESSAGE",
				"METHOD",
				"METHOD-ID",
				"MODE",
				"MODE-1",
				"MODE-2",
				"MODE-3",
				"MODIFY",
				"MODULES",
				"MORE-LABELS",
				"MOVE",
				"MULTICON",
				"MULTICONVERSATIONMODE",
				"MULTIPLE",
				"MULTIPLY",
				"NAMED",
				"NATIONAL",
				"NATIONAL-EDITED",
				"NATIVE",
				"NEGATIVE",
				"NEXT",
				"NO",
				"NOMINAL",
				"NONE",
				"NOT",
				"NOTE",
				"NULL",
				"NULLS",
				"NUMBER",
				"NUMERIC",
				"NUMERIC-EDITED",
				"OBJECT",
				"OBJECT-COMPUTER",
				"OCCURS",
				"OF",
				"OFF",
				"OMITTED",
				"ON",
				"ONLY",
				"OPEN",
				"OPTIONAL",
				"OR",
				"ORDER",
				"ORGANIZATION",
				"OTHER",
				"OTHERWISE",
				"OUTPUT",
				"OVERFLOW",
				"OVERLINE",
				"OVERRIDE",
				"OWNER",
				"PACKED-DECIMAL",
				"PADDING",
				"PAGE",
				"PAGE-COUNTER",
				"PARAGRAPH",
				"PASSWORD",
				"PERFORM",
				"PF",
				"PH",
				"PIC",
				"PICTURE",
				"PLUS",
				"POINTER",
				"POSITION",
				"POSITIONING",
				"POSITIVE",
				"PREFIX",
				"PRESENT",
				"PREVIOUS",
				"PRINTING",
				"PRIOR",
				"PROCEDURE",
				"PROCEDURES",
				"PROCEED",
				"PROCESSING",
				"PROGRAM",
				"PROGRAM-ID",
				"PROGRAM-STATUS",
				"PROMPT",
				"PROPERTY",
				"PROTECTED",
				"PROTOPTYPE",
				"PURGE",
				"QUEUE",
				"QUOTE",
				"QUOTES",
				"RAISE",
				"RAISING",
				"RANDOM",
				"RANGE",
				"RD",
				"READ",
				"READY",
				"REALM",
				"RECEIVE",
				"RECONNECT",
				"RECORD",
				"RECORD-NAME",
				"RECORD-OVERFLOW",
				"RECORDING",
				"RECORDS",
				"REDEFINES",
				"REEL",
				"REFERENCE",
				"REFERENCES",
				"RELATION",
				"RELATIVE",
				"RELEASE",
				"RELOAD",
				"REMAINDER",
				"REMARKS",
				"REMOVAL",
				"RENAMES",
				"REORG-CRITERIA",
				"REPEATED",
				"REPLACE",
				"REPLACING",
				"REPORT",
				"REPORTING",
				"REPORTS",
				"REPOSITORY",
				"RERUN",
				"REQUIRED",
				"RESERVE",
				"RESET",
				"RETAINING",
				"RETRIEVAL",
				"RETURN",
				"RETURNING",
				"RETURN-CODE",
				"REVERSE-VIDEO",
				"REVERSED",
				"REWIND",
				"REWRITE",
				"RF",
				"RH",
				"RIGHT",
				"RIGHT-JUSTIFY",
				"ROLL-OUT",
				"ROLLBACK",
				"ROUNDED",
				"RUN",
				"SA",
				"SAME",
				"SAVED-AREA",
				"SCREEN",
				"SD",
				"SEARCH",
				"SECTION",
				"SECURITY",
				"SECURE",
				"SEEK",
				"SELF",
				"SEGMENT",
				"SEGMENT-LIMIT",
				"SELECT",
				"SELECTED",
				"SELECTIVE",
				"SEND",
				"SENTENCE",
				"SEPARATE",
				"SEQUENCE",
				"SEQUENTIAL",
				"SERVICE",
				"SESSION",
				"SESSION-ID",
				"SET",
				"SHARED",
				"SHIFT-IN",
				"SHIFT-OUT",
				"SIGN",
				"SIMPLE",
				"SINGLE",
				"SIZE",
				"SKIP1",
				"SKIP2",
				"SKIP3",
				"SORT",
				"SORT-CONTROL",
				"SORT-CORE-SIZE",
				"SORT-FILE-SIZE",
				"SORT-MESSAGE",
				"SORT-MERGE",
				"SORT-MODE-SIZE",
				"SORT-RETURN",
				"SORT-STATUS",
				"SOURCE",
				"SOURCE-COMPUTER",
				"SPACE",
				"SPACE-FILL",
				"SPACES",
				"SPECIAL-NAMES",
				"STANDARD",
				"STANDARD-1",
				"STANDARD-2",
				"START",
				"STATION",
				"STATIONS",
				"STATUS",
				"STOP",
				"STORE",
				"STRING",
				"SUB-QUEUE-1",
				"SUB-QUEUE-2",
				"SUB-QUEUE-3",
				"SUBRANGE",
				"SUB-SCHEMA",
				"SUBSCHEMA-NAME",
				"SUBTRACT",
				"SUCCESSIVE",
				"SUFFIX",
				"SUM",
				"SUPER",
				"SUPPRESS",
				"SYMBOLIC",
				"SYNC",
				"SYNCHRONIZED",
				"TABLE",
				"TALLY",
				"TALLYING",
				"TAPE",
				"TENANT",
				"TENNANT",
				"TERMINAL",
				"TERMINATE",
				"TEST",
				"TEXT",
				"THAN",
				"THEN",
				"THROUGH",
				"THRU",
				"TIME",
				"TIMEOUT",
				"TIMES",
				"TITLE",
				"TO",
				"TOP",
				"TRACE",
				"TRACK",
				"TRACK-AREA",
				"TRACK-LIMIT",
				"TRACK-OVERFLOW",
				"TRACKS",
				"TRAILING",
				"TRAILING-SIGN",
				"TRANSACTION",
				"TRANSCEIVE",
				"TRUE",
				"TYPE",
				"TYPEDEF",
				"UNDERLINE",
				"UNEQUAL",
				"UNIT",
				"UNIVERSAL",
				"UNLOCK",
				"UNSTRING",
				"UNTIL",
				"UP",
				"UPDATE",
				"UPON",
				"USAGE",
				"USAGE-MODE",
				"USE",
				"USING",
				"VALID",
				"VALIDATE",
				"VALUE",
				"VALUES",
				"VARYING",
				"WAIT",
				"WHEN",
				"WHEN-COMPILED",
				"WITH",
				"WITHIN",
				"WORDS",
				"WORKING-STORAGE",
				"WRITE",
				"WRITE-ONLY",
				"ZER",
				"ZERO-FILL",
				"ZEROES",
				"ZEROS"
			};

			Array.Sort(keywordList);
			Array.Reverse(keywordList);

			return keywordList;
		}
	}
}